package com.ecoolex.chinadutyfree.retailer.core.manager;

import com.ecoolex.chinadutyfree.retailer.core.dao.DirectMailGoodsOrderShippedRecordDAO;
import com.ecoolex.chinadutyfree.retailer.entity.DirectMailGoodsOrder;
import com.ecoolex.chinadutyfree.retailer.entity.DirectMailGoodsOrderDetail;
import com.ecoolex.chinadutyfree.retailer.entity.DirectMailGoodsOrderShippedRecord;
import com.ecoolex.chinadutyfree.retailer.entity.DirectMailGoodsOrderShippedRecordExample;
import com.ecoolex.chinadutyfree.retailer.enums.DirectMailGoodsOrderStatus;
import com.ecoolex.framework.common.enums.ResultCode;
import com.ecoolex.framework.common.util.BizAssert;
import com.ecoolex.framework.common.util.Check;
import com.google.common.collect.Lists;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import org.springframework.transaction.annotation.Transactional;

import java.time.Instant;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class DirectMailGoodsOrderShippedRecordManager {
    @Autowired
    private DirectMailGoodsOrderShippedRecordDAO dao;

    @Autowired
    private DirectMailGoodsDeliveryMannerManager goodsDeliveryMannerManager;

    @Autowired
    private DirectMailGoodsOrderManager directMailGoodsOrderManager;

    @Autowired
    private DirectMailGoodsOrderDetailManager goodsOrderDetailManager;

    private List<DirectMailGoodsOrderDetail> verifyAndReturnDetail(DirectMailGoodsOrder order, DirectMailGoodsOrderShippedRecord record, List<Integer> detailIdList, boolean isUpdateDetail) {
        // 验证发货的信息是否正确
        BizAssert.isTrue(Check.notNull(record.getDeliveryMannerId()), ResultCode.VERIFY.build(20), "配送方式不能为空");

        BizAssert.isTrue(Check.notNullOrTrimEmpty(record.getDeliveryNo()), ResultCode.VERIFY.build(21), "发货单号不能为空");

        BizAssert.isTrue(Check.notNull(record.getDeliveryTime()), ResultCode.VERIFY.build(22), "发货时间不能为空");

        BizAssert.isTrue(record.getDeliveryTime().after(order.getPaymentTime()),ResultCode.VERIFY.build(23),"发货时间必须在支付时间之后");

        DirectMailGoodsOrderShippedRecord old = getByInfo(order.getOrderId(),//
                record.getDeliveryMannerId(), //
                record.getDeliveryNo(), //
                record.getShippedRecordId());
        BizAssert.isTrue(Check.isNull(old), ResultCode.VERIFY.build(24), "发货单号已存在");

        if (isUpdateDetail) {
            // 验证detailList数据是否正确
            BizAssert.isTrue(Check.notNullOrEmpty(detailIdList), ResultCode.VERIFY.build(30), "关联订单详情不能为空");
            List<DirectMailGoodsOrderDetail> detailList = detailIdList.stream().map(detailId -> {
                DirectMailGoodsOrderDetail detail = goodsOrderDetailManager.getByOrderId(order.getOrderId(), detailId);
                BizAssert.isTrue(Check.notNull(detail), ResultCode.VERIFY.build(31), "订单详情不能为空");
                // 检查商品是否支持该发货方式
//                zhangdongjie (zhangdongjie@ecoolex.com) 2020-07-03 15:17:13 删除配送方式检查
//                BizAssert.isTrue(goodsDeliveryMannerManager.isSupport(detail.getDirectMailGoodsId(),
//                    record.getDeliveryMannerId()), ResultCode.VERIFY.build(32), "{} 不支持当前物流方式", detail.getName());
                return detail;
            }).collect(Collectors.toList());
            return detailList;
        } else {
            BizAssert.isTrue(Check.isNullOrEmpty(detailIdList), ResultCode.VERIFY.build(33), "关联订单详情无法修改, 必须为空");
            return Lists.newArrayList();
        }
    }

    @Transactional
    public DirectMailGoodsOrderShippedRecord addShippedRecord(DirectMailGoodsOrder order, DirectMailGoodsOrderShippedRecord record, List<Integer> detailIdList, String createUser) {
        // 验证订单状态是否可以发货
        BizAssert.isTrue(DirectMailGoodsOrderStatus.canShipped(order.getStatus()),
                ResultCode.VERIFY.build(10),
                "待发货才能发货");

        List<DirectMailGoodsOrderDetail> detailList = verifyAndReturnDetail(order, record, detailIdList, true);

        // 插入发货数据
        DirectMailGoodsOrderShippedRecord shippedRecord = create(order, record, createUser);

        // 修改detail数据
        // 验证修改是否成功
        detailList.forEach(detail -> {
            boolean flag = goodsOrderDetailManager.shipped(shippedRecord, detail, createUser);
            BizAssert.isTrue(flag, ResultCode.VERIFY.build(31), "订单详情[{}]发货失败", detail.getName());
        });

        // 未发货; 添加/修改(关联/取消关联)/删除

        // 如果已发货; 修改物流单号和配送方式

        // 暂无物流信息

        // 刷新待发货状态
        //directMailGoodsOrderManager.refreshShippingStatus(order.getOrderId());

        return shippedRecord;
    }

    @Transactional
    public DirectMailGoodsOrderShippedRecord updateShippedRecord(DirectMailGoodsOrderShippedRecord record, List<Integer> detailIdList, String updateUser) {
        // 查询订单
        DirectMailGoodsOrder order = directMailGoodsOrderManager.getByOrderId(record.getOrderId());

        record.setUpdateUser(updateUser);
        record.setUpdateTime(Date.from(Instant.now()));
        dao.updateByPrimaryKeySelective(record,
                DirectMailGoodsOrderShippedRecord.Column.deliveryMannerId,
                DirectMailGoodsOrderShippedRecord.Column.deliveryNo,
                DirectMailGoodsOrderShippedRecord.Column.deliveryTime,
                DirectMailGoodsOrderShippedRecord. Column.updateUser,
                DirectMailGoodsOrderShippedRecord. Column.updateTime);

        boolean isUpdateDetail = DirectMailGoodsOrderStatus.canEditShippedInfo(order.getStatus());

        List<DirectMailGoodsOrderDetail> detailList
                = verifyAndReturnDetail(order, record, detailIdList, isUpdateDetail);

        if (isUpdateDetail) {
            detailList.forEach(detail -> {
                boolean flag = goodsOrderDetailManager.shipped(record, detail, updateUser);
                BizAssert.isTrue(flag, ResultCode.VERIFY.build(31), "订单详情[{}]发货失败", detail.getName());
            });
            // 清空无效的
            goodsOrderDetailManager.cleanShippedRecordId(order.getOrderId(),
                    record.getShippedRecordId(),
                    detailIdList,
                    updateUser);
        }

        return record;
    }

    @Transactional
    public void delete(DirectMailGoodsOrderShippedRecord record, String updateUser) {
        // 查询订单
        DirectMailGoodsOrder order = directMailGoodsOrderManager.getByOrderId(record.getOrderId());
        BizAssert.isTrue(DirectMailGoodsOrderStatus.canEditShippedInfo(order.getStatus()),
                ResultCode.VERIFY.build(10),
                "无法进行删除发货记录");

        record.setDeleted(DirectMailGoodsOrderShippedRecord.IS_DELETED);
        record.setUpdateUser(updateUser);
        record.setUpdateTime(Date.from(Instant.now()));

        dao.updateByPrimaryKeySelective(record,
                DirectMailGoodsOrderShippedRecord.Column.deleted, DirectMailGoodsOrderShippedRecord.Column.updateUser, DirectMailGoodsOrderShippedRecord.Column.updateTime);
        // 清理
        goodsOrderDetailManager.cleanShippedRecordId(order.getOrderId(), record.getShippedRecordId(), null, updateUser);

        // 刷新发货中状态
        //directMailGoodsOrderManager.refreshShippingStatus(order.getOrderId());
    }

    private DirectMailGoodsOrderShippedRecord getByInfo(Integer orderId, Integer deliveryMannerId, String deliveryNo, Integer notIncludeShippedRecordId) {
        DirectMailGoodsOrderShippedRecordExample example = new DirectMailGoodsOrderShippedRecordExample();
        DirectMailGoodsOrderShippedRecordExample.Criteria criteria = example.createCriteria();
        criteria.andOrderIdEqualTo(orderId).andDeliveryMannerIdEqualTo(deliveryMannerId).andDeliveryNoEqualTo(
                deliveryNo).andDeletedEqualTo(DirectMailGoodsOrderShippedRecord.NOT_DELETED);
        if (Check.notNull(notIncludeShippedRecordId)) {
            criteria.andShippedRecordIdNotEqualTo(notIncludeShippedRecordId);
        }
        return dao.selectOneByExample(example);
    }

    private DirectMailGoodsOrderShippedRecord create(DirectMailGoodsOrder order, DirectMailGoodsOrderShippedRecord record, String createUser) {
        record.setOrderId(order.getOrderId());
        record.setDeleted(DirectMailGoodsOrder.NOT_DELETED);
        record.setCreateUser(createUser);
        record.setCreateTime(Date.from(Instant.now()));
        record.setUpdateUser(createUser);
        record.setUpdateTime(Date.from(Instant.now()));
        dao.insert(record);
        return record;
    }

    public List<DirectMailGoodsOrderShippedRecord> queryByOrderId(Integer orderId) {
        DirectMailGoodsOrderShippedRecordExample example = new DirectMailGoodsOrderShippedRecordExample();
        example.createCriteria().andOrderIdEqualTo(orderId).andDeletedEqualTo(
                DirectMailGoodsOrderShippedRecord.NOT_DELETED);
        return dao.selectByExample(example);
    }

    public DirectMailGoodsOrderShippedRecord getById(Integer shippedRecordId) {
        return dao.selectByPrimaryKeyWithLogicalDelete(shippedRecordId, DirectMailGoodsOrderShippedRecord.NOT_DELETED);
    }
}